package com.two.screen.water.balance.utils

import com.lzy.okgo.OkGo
import com.lzy.okgo.model.HttpHeaders
import com.lzy.okgo.model.HttpMethod
import com.lzy.okgo.model.HttpParams
import com.lzy.okgo.request.base.Request
import com.lzy.okrx2.adapter.ObservableBody
import com.two.screen.water.balance.net.JsonConvert
import com.trello.rxlifecycle2.android.ActivityEvent
import com.trello.rxlifecycle2.android.FragmentEvent
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity
import com.trello.rxlifecycle2.components.support.RxFragment
import io.reactivex.Observable
import io.reactivex.ObservableTransformer
import io.reactivex.Scheduler
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.annotations.NonNull
import io.reactivex.schedulers.Schedulers
import java.lang.reflect.Type


/**
 * 创建者     Noel
 * 创建时间   2017/9/14 9:59
 */

object RxUtils {

    /*发射在io线程，接受在ui线程*/
    fun <T> io(): ObservableTransformer<T, T> {
        return schedulerTransformer(Schedulers.io())
    }

    fun <T> nThread(): ObservableTransformer<T, T> {//new Thread
        return schedulerTransformer(Schedulers.newThread())
    }

    private fun <T> schedulerTransformer(scheduler: Scheduler): ObservableTransformer<T, T> {
        return ObservableTransformer { observable ->
            observable.subscribeOn(scheduler).observeOn(AndroidSchedulers.mainThread(), true)
        }


    }

    fun <T> aLifecycle(fragment: RxFragment): ObservableTransformer<T, T> {
        //return { observable -> observable.compose(fragment.bindUntilEvent<T>(FragmentEvent.DESTROY)) }
        return ObservableTransformer { observable -> observable.compose(fragment.bindUntilEvent(FragmentEvent.DESTROY)) }
    }

    /*绑定声明周期*/
    fun <T> aLifecycle(activity: RxAppCompatActivity): ObservableTransformer<T, T> {
        return aLifecycle(activity, ActivityEvent.DESTROY)
    }

    fun <T> aLifecycle(activity: RxAppCompatActivity, @NonNull event: ActivityEvent): ObservableTransformer<T, T> {
        return ObservableTransformer { observable -> observable.compose(activity.bindUntilEvent(event)) }
    }

    /*一下与okgo网络请求有关*/

    fun <T> request(method: HttpMethod, url: String, type: Type): Observable<T> {
        return request(method, url, type, null)
    }

    fun <T> request(method: HttpMethod, url: String, type: Type, params: HttpParams?): Observable<T> {
        return request(method, url, type, params, null)
    }

    fun <T> request(method: HttpMethod, url: String, type: Type, params: HttpParams?, headers: HttpHeaders?): Observable<T> {
        return request(method, url, type, null, params, headers)
    }

    fun <T> request(method: HttpMethod, url: String, clazz: Class<T>): Observable<T> {
        return request(method, url, clazz, null)
    }

    fun <T> request(method: HttpMethod, url: String, clazz: Class<T>, params: HttpParams?): Observable<T> {
        return request(method, url, clazz, params, null)
    }

    fun <T> request(method: HttpMethod, url: String, clazz: Class<T>, params: HttpParams?, headers: HttpHeaders?): Observable<T> {
        return request(method, url, null, clazz, params, headers)
    }

    fun <T> request(method: HttpMethod, url: String, type: Type?, clazz: Class<T>?, params: HttpParams?, headers: HttpHeaders?): Observable<T> {
        val request: Request<T, out Request<*, *>>
        if (method == HttpMethod.GET) request = OkGo.get(url)
        else if (method == HttpMethod.POST) request = OkGo.post(url)
        else if (method == HttpMethod.PUT) request = OkGo.put(url)
        else if (method == HttpMethod.DELETE) request = OkGo.delete(url)
        else if (method == HttpMethod.HEAD) request = OkGo.head(url)
        else if (method == HttpMethod.PATCH) request = OkGo.patch(url)
        else if (method == HttpMethod.OPTIONS) request = OkGo.options(url)
        else if (method == HttpMethod.TRACE) request = OkGo.trace(url)
        else request = OkGo.get(url)

        request.headers(headers)
        request.params(params)
        if (type != null) {
            request.converter(JsonConvert<T>(type))
        } else if (clazz != null) {
            request.converter(JsonConvert<T>(clazz))
        } else {
            request.converter(JsonConvert<T>())
        }
        return request.adapt(ObservableBody())
    }
}
